package cn.edu.sjtu;

import hu.uw.pallergabor.dedexer.Dedexer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import cn.edu.sjtu.dfa.Binop;
import cn.edu.sjtu.dfa.DataContainer;
import cn.edu.sjtu.dfa.Instruction;
import cn.edu.sjtu.dfa.Move;
import cn.edu.sjtu.dfa.Register;

public class DataFlowAnalyzer {
	public static HashMap<String, HashMap<String, List<Instruction>>> ils;
	public static HashMap<Long, Long> filePos2Line;	// TODO
	public static HashMap<String, Integer> objMap;
	
	public static boolean isDataFlowAnalysis = false;
	
	private String inPath;
	private String outPath;
	
	public DataFlowAnalyzer(String out, String in) {
		outPath = out;
		inPath = in;
	}
	
	public void Analyse() {
		ils = new HashMap<String, HashMap<String, List<Instruction>>>();
		filePos2Line = new HashMap<Long, Long>();
		objMap = new HashMap<String, Integer>();
		isDataFlowAnalysis = true;
		
		Dedexer dedexer = new Dedexer();
		String[] args = { "-r", "-d", outPath, inPath };
		dedexer.run(args);
		
//		isDataFlowAnalysis = false;
	}
	
	public void Print() {
		if (ils != null) {
			
			Iterator it = ils.entrySet().iterator();
			while (it.hasNext()) {
				
				Map.Entry entry = (Map.Entry) it.next();

//				if (!entry.getKey().toString().equals("cn.edu.sjtu.test.Test"))
//					continue;

				System.out.println("================================" +
						"\nClass: " + entry.getKey() + "\n" +
								"==================================");
				HashMap<String, List<Instruction>> methodList = (HashMap<String, List<Instruction>>) entry.getValue();
				if(methodList != null){
					Iterator mIt = methodList.entrySet().iterator();
					while(mIt.hasNext()){
						Map.Entry mEntry = (Entry) mIt.next();
						System.out.println(".....................................\nMethod: " + mEntry.getKey() + "\n.....................................");
						List<Instruction> list = (List<Instruction>) mEntry.getValue();
						if (list != null) {
							
							for (Instruction i : list) {
								System.out.println("\tInstruction Length: " + i.getinstrLength());
								System.out.println("\tLine: " + filePos2Line.get(i.getFilePosition()));
								System.out.println("\t" + i.toString());
								System.out.println("\tDex Code: \n" + i.getDexerString());
								System.out.println("-------------------------------");
							}
						}
					}
					
				}
				
			}
		}
		
	}
	
	public static void main(String[] args) {

		long a = -999999999;
		Register dc = new Register("asdda", null, 1);
		Binop bbb = new Binop(null, dc, null, "aaa");
		System.out.println(dc.getClass().getName() + bbb.getRegister2().getClass().getName());
		List<Instruction> test = new ArrayList<Instruction>();
		test.add(new Move(new Register("long", null, 1), new Register("int", null, 2)));
		System.out.println(test.get(0));
		System.out.println((int) a);
		DataFlowAnalyzer dfa = new DataFlowAnalyzer("Q:\\Temp\\", "C:\\TDDOWNLOAD\\courseware\\eclipse-jee-helios-win32\\eclipse\\workspace2\\Helloworld\\bin\\classes.dex");

		dfa.Analyse();
		dfa.Print();
	}
}
